// stores/socket.js
import {
	defineStore
} from 'pinia';
import {
	baseUrl,
} from '@/common/base';
import {
	checkRepeatLoginApi,
	forcedOfflineApi,
} from '@/api/socket';
import {
	runtimeQuit,
} from '@/utils/index';
import {
	useUserStore,
} from "./user";
import {
	useContactsStore,
} from './contacts';
import {
	useChatStore,
} from './chat'
import {
	dayjs,
} from '@/utils/dayjs.js';

export const useSocketStore = defineStore('socket', {
	state: () => {
		return {
			userId: '', // 在首页登录成功加载时 获取值
			socketTask: null, // socket实例
			isOpenSocket: false, // 避免重复连接
			isReconnect: false, // 检测是否在重新连接
			isRepeatConnect: false, // 检测是否在相同设备上重复登录
			heartbeatInterval: null, // 检测服务器端是否还活着
			timeout: 5000, // 多少秒执行检测
			waitDep: [], // 等待时收集依赖的容器
		};
	},
	actions: {
		/**
		 * 仅供内部使用，通知所有收集到的依赖
		 */
		_notify() {
			for (let i = 0; i < this.waitDep.length; i++) {
				this.send(this.waitDep[i]);
			}
			this.waitDep = [];
		},
		/**
		 * 仅供内部使用，确认当前用户是否在相同设备上重复登录
		 */
		async _checkRepeatLogin() {
			try {
				let {
					data
				} = await checkRepeatLoginApi({
					conId: this.userId + "_app",
				});
				return data.data.connection;
			} catch (e) {
				throw Error(e);
			}
		},
		/**
		 * 重新连接
		 */
		async _reconnect() {
			if (!this.isReconnect) {
				uni.showLoading({
					title: '重新连接中',
					mask: true,
				});
			}

			this.isRepeatConnect = await this._checkRepeatLogin();
			if (this.isRepeatConnect) {
				this.isReconnect = true;
				this._reconnect();
			} else {
				this.isReconnect = false;
				this.initSocket();
				uni.hideLoading();
			}
		},
		/**
		 * 开始初始化chat
		 */
		async initChat() {
			try {
				this.isRepeatConnect = await this._checkRepeatLogin();
				if (this.isRepeatConnect) {
					uni.showModal({
						title: '提示',
						content: '当前账号已经登录在其他页面,是否强制下线',
						success: async (res) => {
							if (res.confirm) {
								let data = await forcedOfflineApi({
									conId: this.userId + "_app",
								});

								this.initSocket();
							} else if (res.cancel) {
								let user = useUserStore();
								user.token = '';
								runtimeQuit();
							}
						}
					});
				} else {
					this.initSocket();
				}
			} catch (e) {
				console.log(e)
			}
		},
		/**
		 * 开始初始化 websocket
		 */
		async initSocket() {
			// 防止设备或网络的延迟，造成影响
			this.isRepeatConnect = await this._checkRepeatLogin();
			if (this.isRepeatConnect) {
				this.initSocket();
				return;
			}

			// 获取websocket实例
			this.socketTask = uni.connectSocket({
				url: baseUrl.socket + `?token=${this.userId}_app`,
				success: (res) => {},
				fail: (err) => {},
			});

			// 监听 WebSocket 连接打开事件
			this.socketTask.onOpen((res) => {
				console.log("WebSocket连接正常！");
				this.isOpenSocket = true;
				getApp()._heartbeat();
			});

			// 注：只有连接正常打开中 ，才能正常收到消息
			this.socketTask.onMessage(({
				data
			}, msg) => {
				msg = JSON.parse(data);
				let contacts = useContactsStore();
				let chat = useChatStore();

				if (msg.type != 9) {
					console.log(msg);
				} else {
					// console.log(msg);
				}

				switch (msg.type) {
					case 1:
						chat.addMsg('friend', msg.uid, {
							"id": msg.id,
							"send": msg.uid,
							"receive": msg.receive.split('_')[0],
							"content": null,
							"sendDate": dayjs(msg.sendDate).format(
								'YYYY-DD-MM hh:mm:ss'),
							"state": 1,
							"dev": msg.dev,
							"groupUsers": null,
							"type": 1,
							"groupId": null,
							"backMsgId": null,
							"backTime": null,
							"isDel": null,
							"info": msg.info,
							"listOfflineMsg": null,
							"offlineMsgCount": null,
							"uid": null,
							"friendId": null,
							"friendBirthday": null,
							"phone": null,
							"email": null,
							"hasDelMsgId": null,
							"sendDateTimestamp": msg.sendDate,
						})
						break;
					case 2:
						chat.addMsg('group', msg.groupId, {
							"id": msg.id,
							"send": msg.send.split('_')[0],
							"receive": msg.receive.split('_')[0],
							"content": null,
							"sendDate": dayjs(msg.sendDate).format(
								'YYYY-DD-MM hh:mm:ss'),
							"state": 1,
							"dev": msg.dev,
							"groupUsers": msg.groupUsers,
							"type": 2,
							"groupId": msg.groupId,
							"backMsgId": null,
							"backTime": null,
							"isDel": null,
							"info": msg.info,
							"listOfflineMsg": null,
							"offlineMsgCount": null,
							"uid": null,
							"friendId": null,
							"friendBirthday": null,
							"phone": null,
							"email": null,
							"hasDelMsgId": null,
							"sendDateTimestamp": msg.sendDate
						})
						break;
					case 3:
						contacts.addBadge('friend', JSON.parse(msg.info).id);
						break;
					case 4:
						contacts.addBadge('group', JSON.parse(msg.info).id);
						break;
					case 5:
						contacts.getGroup({
							gid: msg.groupId,
						});
						break;
					case 7:
						contacts.getFriend(msg.uid);
						break;
					case 8:
						switch (msg.oldType) {
							case 1:
								chat.addMsg('friend', msg.oldReceive, {
									"id": msg.id,
									"send": msg.uid,
									"receive": msg.oldReceive,
									"content": null,
									"sendDate": dayjs(msg.sendDate).format(
										'YYYY-DD-MM hh:mm:ss'),
									"state": 1,
									"dev": msg.dev,
									"groupUsers": null,
									"type": 1,
									"groupId": null,
									"backMsgId": null,
									"backTime": null,
									"isDel": null,
									"info": msg.info,
									"listOfflineMsg": null,
									"offlineMsgCount": null,
									"uid": null,
									"friendId": null,
									"friendBirthday": null,
									"phone": null,
									"email": null,
									"hasDelMsgId": null,
									"sendDateTimestamp": msg.sendDate,
								});
								break;
							case 2:
								chat.addMsg('group', msg.groupId, {
									"id": msg.id,
									"send": msg.send.split('_')[0],
									"receive": msg.receive.split('_')[0],
									"content": null,
									"sendDate": dayjs(msg.sendDate).format(
										'YYYY-DD-MM hh:mm:ss'),
									"state": 1,
									"dev": msg.dev,
									"groupUsers": msg.groupUsers,
									"type": 2,
									"groupId": msg.groupId,
									"backMsgId": null,
									"backTime": null,
									"isDel": null,
									"info": msg.info,
									"listOfflineMsg": null,
									"offlineMsgCount": null,
									"uid": null,
									"friendId": null,
									"friendBirthday": null,
									"phone": null,
									"email": null,
									"hasDelMsgId": null,
									"sendDateTimestamp": msg.sendDate
								})
								break;
							default:
								break;
						}

						if (msg.dev !== 'app') {
							switch (msg.oldType) {
								case 16:
								case 17:
									if (msg.groupUsers && JSON.parse(msg.groupUsers).includes(this
											.userid)) return;
									contacts.getGroup({
										gid: msg.groupId
									});
									break;
								case 22:
									let index = contacts.friendList.findIndex(item => item
										.friendId ==
										msg.oldReceive);
									if (index !== -1) {
										contacts.friendList.splice(index, 1);
									}
									break;
								default:
									break;
							}
						}
						break;
					case 16:
					case 17:
						contacts.getGroup({
							gid: msg.groupId
						});
						break;
					case 20:
						let user = useUserStore();
						user.token = '';
						this.socketTask.close();
						runtimeQuit();
						break;
					case 22:
						let index = contacts.friendList.findIndex(item => item.friendId == msg.uid);
						if (index !== -1) {
							contacts.friendList.splice(index, 1);
						}
						break;
					default:
						break;
				}
				uni.setStorageSync('timeExpired', Date.now()); // 缓存当前登录时间
			});

			// 监听 WebSocket 错误事件
			this.socketTask.onError(async () => {
				console.log('WebSocket连接打开失败，请检查！');
				this.isOpenSocket = false;
				clearInterval(this.heartbeatInterval);
				await forcedOfflineApi(this.userId);
				this._reconnect();
			});

			// WebSocket 连接关闭事件的回调函数
			this.socketTask.onClose(async () => {
				console.log("已经被关闭了")
				this.isOpenSocket = false;
				clearInterval(this.heartbeatInterval);
				await forcedOfflineApi(this.userId);
			});
		},
		// 发送消息时，对消息进行处理
		send(value, msg) {
			msg = {
				send: this.userId + "_app",
				uid: this.userId,
				dev: "app",
				...value
			};

			if (this.isOpenSocket) {
				// 注：只有连接正常打开中 ，才能正常成功发送消息
				this.socketTask.send({
					data: JSON.stringify(msg),
					fail: () => {
						msg.type != 9 && this.waitDep.push(msg);
					},
				});
			} else {
				msg.type != 9 && this.waitDep.push(msg);
			}
		},
		// 关闭websocket连接
		closeSocket() {
			this.socketTask.close();
		},
	},
	unistorage: {
		paths: ['userId', 'waitDep'] // 需要缓存的路径
	}
});
